/*

  The contents of this file are subject to the Mozilla Public License Version
  1.1 (the "License"); you may not use this file except in compliance with
  the License. You may obtain a copy of the License at 
  
           http://www.mozilla.org/MPL/ 
  
  Software distributed under the License is distributed on an "AS IS" basis,
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  for the specific language governing rights and limitations under the License. 
  
  The Original Code is Indigo framework applicatif.
  
  The Initial Developer of the Original Code is
  Olivier Bugalotto (aka Iteratif) <olivier.bugalotto@iteratif.net>.
  Portions created by the Initial Developer are Copyright (C) 2004-2008
  the Initial Developer. All Rights Reserved.
  
  Contributor(s) :
  
*/
package indigo.collections
{
	import flash.errors.IllegalOperationError;
	import flash.utils.Proxy;
	import flash.utils.flash_proxy;

	/**
	 *
	 * Implementation de l'interface <code>IList</code>.<br>
	 * La classe <code>ArrayList</code> represente une collection non generique d'objets
	 * <br>dont les objets sont accessible a partir d'un index.
	 * 
	 * @example Voici un exemple qui manipule des chaines de caracteres:
	 * <listing version="3.0">
	 * var list:ArrayList = new ArrayList(["France","Allemagne","Angleterre"]);
	 * trace(list[2]); // Angleterre
	 * 
	 * if(list.contains("Allemagne")) {
	 * 		list.insert(list.indexOf("Allemagne"),"Suisse");
	 * }
	 * 
	 * trace(list); // France,Suisse,Allemagne,Angleterre
	 * </listing>
	 * 
	 *
	 * @see IList
	 */
	public class ArrayList extends Proxy implements IList
	{
		private var _items:Array;
		
		/**
		 * Creer un nouvel objet <code>ArrayList</code>
		 * @param source	Reference d'un tableau permettant d'initialiser un objet <code>ArrayList</code>
		 * 
		 */
		public function ArrayList(source:Array = null)
		{
			super();
			if(source)
				_items = source;
			else
				_items = [];
		}
		
		/**
		 * Obtenir un element depuis son index dans <code>ArrayList</code>
		 * a l'aide de la syntaxe [].
		 * 
		 * @param name
		 * @return 
		 * 
		 */
		flash_proxy override function getProperty(name:*):* {
			return getItemAt(name);
		}
		
		/**
		 * Definit un element depuis un index specifie dans <code>ArrayList</code>
		 * @param name
		 * @param value
		 * 
		 */
		flash_proxy override function setProperty(name:*, value:*):void {
			insert(name,value);
		}
		
		/**
		 * 
		 * @return 
		 * @inheritDoc
		 */
		public function getEnumerator():IEnumerator
		{
			return new ArrayListEnumerator(_items);
		}
		
		/**
		 * 
		 * @return 
		 * @inheritDoc
		 */
		public function get count():uint
		{
			return _items.length;
		}
		
		/**
		 * 
		 * @param item
		 * @inheritDoc
		 */
		public function add(item:Object):void
		{
			_items.push(item);
		}
		
		/**
		 * 
		 * @return 
		 * @inheritDoc
		 */
		public function arrayTo():Array
		{
			return _items;
		}
		
		/**
		 * 
		 *@inheritDoc 
		 */
		public function clear():void
		{
			_items = [];
		}
		
		/**
		 * 
		 * @param item
		 * @return 
		 * @inheritDoc
		 */
		public function contains(item:Object):Boolean
		{
			var e:IEnumerator = getEnumerator();
			while(e.moveNext()) {
				if(e.current == item)
					return true;
			}
			return false;
		}
		
		/**
		 * 
		 * @param item
		 * @return 
		 * @inheritDoc
		 */
		public function indexOf(item:Object):int
		{
			return _items.indexOf(item);
		}
		
		/**
		 * 
		 * @param index
		 * @param item
		 * @inheritDoc
		 */
		public function insert(index:int, item:Object):void
		{
			if(index < 0 || index > _items.length) throw new IllegalOperationError();
			
			_items[index] = item;
		}
		
		/**
		 * 
		 * @param item
		 * @inheritDoc
		 */
		public function remove(item:Object):void
		{
			var index:int = indexOf(item);
			_items.splice(index,1);
		}
		
		/**
		 * 
		 * @param index
		 * @inheritDoc
		 */
		public function removeAt(index:int):void {
			var item:Object = getItemAt(index);
			remove(item);
		}

		/**
		 * 
		 * @param index
		 * @return 
		 * @inheritDoc
		 */
		public function getItemAt(index:int):Object
		{
			if(index < 0 || index > _items.length) throw new IllegalOperationError();
			
			return _items[index];
		}
		
		/**
		 * Affiche dans une chaine de caracteres les elements contenus dans <code>ArrayList</code>
		 * @return 
		 * 
		 */
		public function toString():String {
			return _items.toString();
		}
		
	}
}
	import indigo.collections.IEnumerator;
	

internal class ArrayListEnumerator implements IEnumerator {
	private var _items:Array;
	private var _position:uint;
	private var _current:Object;
	
	public function get current():Object {
		return _current;
	}
	
	public function ArrayListEnumerator(items:Array) {
		_items = items;
		reset();
	}
	
	public function moveNext():Boolean {
		_current = _items[_position++];
		if(_current) return true;
		return false;
	}
	
	public function reset():void {
		_position = 0;
	}
}